#include "stdafx.h"
#include "GemsecUtilities.h"
#include "ManagedCryptBlob.h"

namespace Safe
{
	// See header file comments for function description
	HashEngine::HashEngine(SupportedHashAlgorithm alg) 
	{ 
		// MD5, SHA1, SHA128, SHA256, SHA284, SHA512
		switch( alg ) { 

			case SupportedHashAlgorithm::MD5:
				this->hashAlg = gcnew System::Security::Cryptography::MD5CryptoServiceProvider();
				break;
			case SupportedHashAlgorithm::SHA1:
				this->hashAlg = gcnew System::Security::Cryptography::SHA1Managed();
				break;
			case SupportedHashAlgorithm::SHA256:
				this->hashAlg = gcnew System::Security::Cryptography::SHA256Managed();
				break;
			case SupportedHashAlgorithm::SHA384:
				this->hashAlg = gcnew System::Security::Cryptography::SHA384Managed();
				break;
			case SupportedHashAlgorithm::SHA512:
				this->hashAlg = gcnew System::Security::Cryptography::SHA512Managed();
				break;
		}
		dataStream = gcnew System::IO::MemoryStream();
	}

	// See header file comments for function description
	HashEngine::~HashEngine() { 
		dataStream->Close();
	}


	// See header file comments for function description
	void HashEngine::Update( array<unsigned char>^ data ) { 
		dataStream->Write( data, 0, data->Length );
	}

	// See header file comments for function description
	void HashEngine::Update( BYTE *pbData, DWORD cbData ) { 
		ManagedCryptBlob^ mcb = gcnew ManagedCryptBlob(pbData,cbData);
		dataStream->Write( mcb->Data, 0, mcb->Length );
	}

	// See header file comments for function description
	array<unsigned char>^ HashEngine::Hash() { 
		array<unsigned char>^ dataArr = dataStream->ToArray();
		dataStream->Close();
		dataArr = hashAlg->ComputeHash(dataArr);
		hashAlg->Clear();
		dataStream = gcnew System::IO::MemoryStream();
		return dataArr;
	}


}